from django.conf import settings
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.http import HttpResponseRedirect

from planner.models import POI
from planner.models import Trip
from planner.models import Vote
from planner.models import TripUser
from planner.forms import TripForm
from planner.forms import PoiForm
from planner.forms import VoteForm
from planner.forms import TripUserRegistrationForm

import oauth2 as oauth
import urlparse
import urllib
import flickrapi


def index(request, auth_form=None, user_form=None):
    # User logged in
    if request.user.is_authenticated():
        return list_trips(request)
        # more queries
        #return render(request, 'users.html', {'user': user,})
    else:
    # User is not logged in
        auth_form = auth_form or AuthenticationForm
        user_form = user_form or TripUserRegistrationForm
        return render(request, 'home.html', {'auth_form': auth_form, 'user_form': user_form, })

def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            # success
            login(request, form.get_user())
            return redirect('/')
        else: 
            # failure
            return index(request, auth_form=form)
    return redirect('/')



def logout_view(request):
    if request.user.is_authenticated():
        logout(request)
    return redirect('/')


def signup(request):
    if request.method == 'POST':
        UserCreationForm(data=request.POST);
        user_form = TripUserRegistrationForm(data=request.POST)
        if user_form.is_valid():
            username = user_form.clean_username()
            password = user_form.clean_password2()
            user_form.save()
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect('/')
        else:
            return index(request, user_form=user_form)
    return redirect('/')



@login_required
def list_users(request):
    user_list = User.objects.all().order_by('username')
    return render(request, 'users.html', {'user_list': user_list,})

@login_required
def detail_user(request, userid=None):
    if User.objects.filter(pk=userid).exists():
        user_detail = User.objects.get(pk=userid)
        own_trips = Trip.objects.filter(owner=userid)
        participates_in = Trip.objects.filter(participants=userid)
        return render(request, 'user_detail.html', {'user_detail': user_detail, 'own_trips': own_trips, 'participates_in': participates_in,})
    else:
        return redirect('/users')

@login_required
def list_trips(request):
    trip_list = Trip.objects.all().order_by('-start_date') 
    return render(request, 'trips.html', {'new_url': '/trips/add', 'trip_list': trip_list, })


@login_required
def detail_trip(request, tripname=None):
    if Trip.objects.filter(pk=tripname).exists():
        trip = Trip.objects.get(pk=tripname)
        is_participating = Trip.objects.filter(pk=tripname, participants=request.user.id).exists()
        is_owner = (trip.owner.id == request.user.id)
        poilist = POI.objects.filter(part_of_trip=tripname).all()
        poi_votes = []
        votes_by_user = [] 
        for p in poilist:
            if Vote.objects.filter(poi=p.id, user=request.user.id).exists():
                votes_by_user.append(p.id)
                poi_votes.append(Vote.objects.filter(poi=p.id).count())
            else:
                poi_votes.append(0)
        poilist = [x for (y,x) in sorted(zip(poi_votes, poilist))]
        poilist.reverse()
        add_poi_uri = request.get_full_path() + "/add_poi"
        edit_trip_uri = request.get_full_path() + "/edit"
        if not tripname or not trip:
            return list_trips(request)
        return render(request, 'trip_detail.html', {'trip_detail': trip, 'is_participating': is_participating, 'is_owner': is_owner , 'add_poi_uri': add_poi_uri,  'poilist':poilist, 'edit_trip_uri':edit_trip_uri, 'user_votes': votes_by_user,})
    else:
        return redirect('/')

@login_required
def new_trip(request, add_trip_form=None):
    add_trip_form = add_trip_form or TripForm()
    action_suffix = 'submit'
    return render(request, 'new_trip.html', {'trip_form' : add_trip_form, 'trip_edit_title': 'Add new Trip', 'action_suffix':action_suffix,})

@login_required
def edit_trip(request, tripname=None, edit_trip_form=None):
    if Trip.objects.filter(pk=tripname).exists():
        trip = Trip.objects.get(pk=tripname)
        edit_trip_form = edit_trip_form or TripForm(instance=trip)
        action_suffix = tripname+'/update'
        return render(request, 'new_trip.html', {'trip_form' : edit_trip_form, 'trip_edit_title': 'Edit Trip','action_suffix': action_suffix,})
    return redirect('/trips')

@login_required
def submit_edited_trip(request, tripname=None):
    if request.method == 'POST':
        if Trip.objects.filter(pk=tripname).exists():
            trip = Trip.objects.get(pk=tripname)
            if request.user.id == trip.owner.id:
                edit_trip_form = TripForm(request.POST, instance=trip)
                if edit_trip_form.is_valid():
                    tripp = edit_trip_form.save(commit=False)
                    edit_trip_form.save_m2m()
                    tripp.save()
                    trip = Trip.objects.get(pk=tripname)
                    trip.participants.add(request.user)
                    trip.save()
                    return redirect('/trips/'+tripname)
    return redirect('/trips')

@login_required
def submit_trip(request):
    if request.method == 'POST':
        add_trip_form = TripForm(request.POST)
        if 'save' in request.POST:
            pass
        else:
            print add_trip_form.errors
        if add_trip_form.is_valid():
            trip = add_trip_form.save(commit=False)
            trip.owner = request.user
            trip.save()
            add_trip_form.save_m2m()
            trip.participants.add(request.user)
            trip.save()
        else:
            return redirect('/wasnotvalid')
    else:
        return redirect('/') 
    return redirect('/trips')


@login_required
def new_poi(request, tripname=None, add_poi_form=None):
    if Trip.objects.filter(pk=tripname).exists():
        trip = Trip.objects.get(pk=tripname)
        if (trip.owner.id == request.user.id):
            trip_name = Trip.objects.get(pk=tripname).trip_name
            add_poi_form = add_poi_form or PoiForm()
            poi_prefix = "Add"
            poi_post_uri = '/trips/'+tripname+'/submit'
            return render(request, 'new_poi.html', { 'poi_form': add_poi_form, 'tripid': tripname, 'trip_name': trip_name,  'poi_prefix': poi_prefix, 'poi_post_uri': poi_post_uri,'is_edit':False})
        else:
            return redirect('/trips')
    else:
        return redirect('/trips')

@login_required
def submit_poi(request, tripname=None):
    if request.method == 'POST':
        if Trip.objects.filter(pk=tripname).exists():
            trip = Trip.objects.get(pk=tripname)
            if request.user.id == trip.owner.id:
                add_poi_form = PoiForm(request.POST)
                if add_poi_form.is_valid():
                    poi = add_poi_form.save(commit=False)
                    poi.part_of_trip = trip
                    poi.save()
                    if poi.is_definitive:
                        data = {'status':'I just set my definitive trip to '+trip.trip_name+' where I will see the '+poi.poi_name}
                        tripuser = TripUser.objects.get(pk=request.user.id)
                        tripuser.last_saved_poi = poi.id
                        tripuser.last_saved_trip = trip.id
                        tripuser.save()
                        if tripuser.access_token is not None:
                            sendMessage(tripuser)
                            return redirect('/trips/'+tripname)
                        return redirect('/twitter')
                    return redirect('/trips/'+tripname) 
            else:
                return redirect('/nirvana')
        return redirect('/trips/haha')
    else:
        return redirect('/trips')

@login_required
def edit_poi(request, tripname=None, poiname=None, edit_poi_form=None):
    if Trip.objects.filter(pk=tripname).exists() and POI.objects.filter(pk=poiname).exists():
        trip = Trip.objects.get(pk=tripname)
        poi  = POI.objects.get(pk=poiname)
        is_owner = trip.owner == request.user
        is_part_of_trip = poi.part_of_trip == trip
        edit_poi_uri = '/trips/'+tripname+'/'+poiname+'/update'
        flickr_search_uri = '/trips/'+tripname+'/'+poiname+'/flickrSearch'
        image_url = poi.image_url
        if not is_owner:
            return redirect('/is_owner')
        if not is_part_of_trip:
            return redirect('/shitshit')
        poi_prefix = "Edit"
        if is_owner and is_part_of_trip:
            edit_poi_form = edit_poi_form or PoiForm(instance=poi)
            return render(request, 'new_poi.html', {'poi_prefix': poi_prefix, 'poi_form': edit_poi_form,  'tripid':tripname, 'trip_name':trip.trip_name, 'poi_post_uri':edit_poi_uri, 'flickr_search_uri':flickr_search_uri, 'is_edit':True, 'image_url':image_url })
    return redirect('/trips')


@login_required
def submit_edited_poi(request, tripname=None, poiname=None):
    if request.method == 'POST':
        if Trip.objects.filter(pk=tripname).exists() and POI.objects.filter(pk=poiname).exists():
            trip = Trip.objects.get(pk=tripname)
            poi = POI.objects.get(pk=poiname)
            edit_poi_form = PoiForm(request.POST, instance=poi)
            if edit_poi_form.is_valid():
                edit_poi_form.save()
                if poi.is_definitive:
                    tripuser = TripUser.objects.get(pk=request.user.id)
                    tripuser.last_saved_poi = poi.id
                    tripuser.last_saved_trip = trip.id
                    tripuser.save()
                    if tripuser.access_token is not None:
                        sendMessage(tripuser)
                        return redirect('/trips/'+tripname)
                    return redirect('/twitter')
    return redirect('/trips')

@login_required
def vote_for_poi(request, tripname=None, poiname=None):
    if request.method == 'POST':
        if Trip.objects.filter(pk=tripname).exists() and POI.objects.filter(pk=poiname).exists():
            trip = Trip.objects.get(pk=tripname)
            poi = POI.objects.get(pk=poiname)
            is_part_of_trip = (poi.part_of_trip.pk == trip.id)
            cuser = User.objects.get(pk=request.user.id)
            is_participating = Trip.objects.filter(pk=tripname, participants=request.user.id).exists()
            if not is_part_of_trip:
                print poi.part_of_trip.pk, tripname, 'haha'
                return redirect('/scheissed')
            if is_part_of_trip and is_participating:
                vote_form = VoteForm(request.POST)
                if vote_form.is_valid():
                    vote_exists = Vote.objects.filter(poi=poi.id, user=request.user.id).exists()
                    if vote_form.cleaned_data['voted']==True:
                        if not vote_exists:
                            pois = poi
                            new_vote = Vote(poi=pois, user=cuser)
                            new_vote.save()
                    else:
                        if vote_exists:
                            old_vote = Vote.objects.get(poi=poi.id, user=request.user.id)
                            old_vote.delete()
                    return redirect('/trips/'+tripname)
    return redirect('/trips')

@login_required
def flickr_search_view(request, tripname=None, poiname=None):
    urls={}
    search_string = request.POST.get('searchstring','not defined searchstring');
    flickr_search_uri = '/trips/'+tripname+'/'+poiname+'/flickrSearch'
    set_image_uri = '/trips/'+tripname+'/'+poiname+'/setimage'
    if request.method == 'POST' and search_string != 'not defined searchstring':
        if Trip.objects.filter(pk=tripname).exists() and POI.objects.filter(pk=poiname).exists():
            api_key = '1e4af0bfbfb344d57b596ab11c74908a';
            api_secret = '199b87c789880dcc'
            flickr = flickrapi.FlickrAPI(api_key,api_secret)
     
            photos=flickr.walk(text=request.POST['searchstring'],per_page='20')
            for i in range(20) :
                photo = photos.next()
                #http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}_[mstzb].jpg
                url='http://farm'+photo.get('farm')+'.staticflickr.com/'+photo.get('server')+'/'+photo.get('id')+'_'+photo.get('secret')+'_m.jpg';
                backlink = 'http://www.flickr.com/photos/'+photo.get('owner')+'/'+photo.get('id')
                urls[url]=backlink
               
    return render(request, 'find_flicker.html', { 'urls':urls, 'flickr_search_uri':flickr_search_uri, 'set_image_uri':set_image_uri })
   
           
@login_required
def setimage (request, tripname=None, poiname=None):
    selectedImage = request.POST.get('selectedImage','not defined image url');
    backlink = request.POST.get('backlink','not defined backlink')
    if request.method == 'POST' and selectedImage != 'not defined image url':
        if Trip.objects.filter(pk=tripname).exists() and POI.objects.filter(pk=poiname).exists():
            poi = POI.objects.get(pk=poiname)
            poi.image_url = selectedImage
            poi.backlink_url = backlink
            poi.save()
            return redirect('/trips/'+tripname+'/'+poiname+'/edit')
    return redirect('/nirvana')
 

@login_required
def twitter_connect(request):
     

    twitter_consumer_key = settings.TWITTER_CONSUMER_KEY
    twitter_consumer_secret = settings.TWITTER_CONSUMER_SECRET

    request_token_url = 'https://twitter.com/oauth/request_token'
    access_token_url = 'https://twitter.com/oauth/access_token'
    authorize_url = 'https://twitter.com/oauth/authorize'
    consumer = oauth.Consumer(twitter_consumer_key,twitter_consumer_secret)
    if ('oauth_verifier' not in request.GET):
        client = oauth.Client(consumer)
        resp, content = client.request(request_token_url, "GET")
        if resp['status'] != '200':
            raise Exception("Invalid response %s." % resp['status'])
        
        request_token = dict(urlparse.parse_qsl(content))
        roauth_token = request_token['oauth_token']
        roauth_token_secret = request_token['oauth_token_secret']
        request.session['roauth_token'] = roauth_token
        request.session['roauth_token_secret'] = roauth_token_secret
        new_authorize_url = authorize_url+'?oauth_token='+request_token['oauth_token']
        return HttpResponseRedirect(new_authorize_url)
    
    if(request.GET['oauth_verifier'] != "" ):
        oauth_verifier = request.GET['oauth_verifier']
        token = oauth.Token(request.session.get('roauth_token', None),request.session.get('roauth_token_secret', None))
        token.set_verifier(oauth_verifier)
        client = oauth.Client(consumer, token)
        
        
        resp, content = client.request(access_token_url, "POST")
        access_token = dict(urlparse.parse_qsl(content))
        
        
        del request.session['roauth_token']
        del request.session['roauth_token_secret']
        
        oauth_token = access_token['oauth_token']
        oauth_token_secret = access_token['oauth_token_secret']
        userid = access_token['user_id']
        screenname = access_token['screen_name']    
        
        if TripUser.objects.filter(pk=request.user.id).exists():
            twitter_user = TripUser.objects.get(pk=request.user.id)
            twitter_user.access_token = oauth_token;
            twitter_user.access_token_secret = oauth_token_secret;
            twitter_user.twitter_id = userid;
            twitter_user.twitter_username = screenname;
            twitter_user.save()
#            access_token = twitter_user.access_token
#            access_token_secret = twitter_user.access_token_secret
#            token = oauth.Token(access_token,access_token_secret)
#            consumer_key = settings.TWITTER_CONSUMER_KEY
#            consumer_secret = settings.TWITTER_CONSUMER_SECRET
#            consumer = oauth.Consumer(consumer_key,consumer_secret)
#            client = oauth.Client(consumer,token)
            
            sendMessage(twitter_user)
    return redirect('/trips/'+twitter_user.last_saved_trip)
        
def sendMessage(user):
            access_token = user.access_token
            access_token_secret = user.access_token_secret
            token = oauth.Token(access_token,access_token_secret)
            consumer_key = settings.TWITTER_CONSUMER_KEY
            consumer_secret = settings.TWITTER_CONSUMER_SECRET
            consumer = oauth.Consumer(consumer_key,consumer_secret)
            client = oauth.Client(consumer,token)
            trip = Trip.objects.get(pk=user.last_saved_trip)
            poi = POI.objects.get(pk=user.last_saved_poi)
            data = {'status':'I just set my definitive trip to '+trip.trip_name+' where I will see the '+poi.poi_name+ ', the trip starts at '+trip.start_date.strftime("%d.%m.%Y")}
            request_uri = 'https://api.twitter.com/1/statuses/update.json'
            resp, content = client.request(request_uri, 'POST', urllib.urlencode(data))
            print content
            print resp
        